package com.wpw.dream.elasticsearch;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;

import org.elasticsearch.action.ActionFuture;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.DisMaxQueryBuilder;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.MultiMatchQueryBuilder.Type;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.QueryStringQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.Before;
import org.junit.Test;

public class ElasticSearchTest {
	TransportClient client;
    @Before
    @SuppressWarnings({ "unchecked" })
    public void before() throws UnknownHostException, InterruptedException, ExecutionException {
        Settings esSettings = Settings.builder()
                .put("cluster.name", "elasticsearch") //设置ES实例的名称
                .put("client.transport.sniff", true) //自动嗅探整个集群的状态，把集群中其他ES节点的ip添加到本地的客户端列表中
                .build();
        client = new PreBuiltTransportClient(esSettings);//初始化client较老版本发生了变化，此方法有几个重载方法，初始化插件等。
        //此步骤添加IP，至少一个，其实一个就够了，因为添加了自动嗅探配置
        client.addTransportAddress(new TransportAddress(InetAddress.getByName("localhost"), 9300));
    }
    
    @Test
    public void index() throws Exception {
        Map<String,Object> infoMap = new HashMap<String, Object>();
        infoMap.put("name", "广告信息11");
        infoMap.put("title", "我的广告22");
        infoMap.put("createTime", new Date());
        infoMap.put("count", 1022);
        
        IndexRequestBuilder prepareIndex = client.prepareIndex("test", "info","100");
        IndexRequestBuilder setSource = prepareIndex.setSource(infoMap);
        ActionFuture<IndexResponse> execute = setSource.execute();
        IndexResponse actionGet = execute.actionGet();
        
        IndexResponse indexResponse = client.prepareIndex("test", "info","100").setSource(infoMap).execute().actionGet();
        System.out.println("id:"+indexResponse.getId());
    }
    
    @Test
    public void get() throws Exception {
        GetResponse response = client.prepareGet("test", "info", "100")  
                .execute().actionGet();
        
        System.out.println("response.getId():"+response.getId());  
        System.out.println("response.getSourceAsString():"+response.getSourceAsString());
        System.out.println("response.getSource():"+response.getSource());
        
    }
    
    @Test
    public void query() throws Exception {
        //term查询
//        QueryBuilder queryBuilder = QueryBuilders.termQuery("age", 50) ;
        //range查询
        QueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("count").gt(50);
        SearchResponse searchResponse = client.prepareSearch("test")
                .setTypes("info")
                .setQuery(rangeQueryBuilder)
                .addSort("count", SortOrder.DESC)
                .setSize(20)
                .execute()
                .actionGet();
        SearchHits hits = searchResponse.getHits(); 
        System.out.println("查到记录数："+hits.getTotalHits());
        SearchHit[] searchHists = hits.getHits();
        if(searchHists.length>0){
            for(SearchHit hit:searchHists){
                String name =  (String) hit.getSourceAsMap().get("name");
                Integer age = (Integer)hit.getSourceAsMap().get("count");
                System.out.format("name:%s ,age :%d \n",name ,age);
            }
        }
    }
    
    @Test
    public void isExsit() {
    	QueryBuilder exsitQueryBuilder = QueryBuilders.existsQuery("title");
    	 SearchResponse searchResponse = client.prepareSearch("test")
                 .setTypes("info")
                 .setQuery(exsitQueryBuilder)
                 .setSize(20)
                 .execute()
                 .actionGet();
    	 SearchHits hits = searchResponse.getHits(); 
         System.out.println("查到记录数："+hits.getTotalHits());
         SearchHit[] searchHists = hits.getHits();
         if(searchHists.length>0){
             for(SearchHit hit:searchHists){
                 String name =  (String) hit.getSourceAsMap().get("name");
                 Integer age = (Integer)hit.getSourceAsMap().get("count");
                 System.out.format("name:%s ,age :%d \n",name ,age);
             }
         }
    }
    
    @Test
    public void complexQuery() {
    	/*localhost:9200/my_index/my_type/_search
    	{
    	    "query": {
    	        "bool": {
    	            "should": [
    	                { "match": { "title": "Brown fox" }},
    	                { "match": { "body":  "Brown fox" }}
    	            ]
    	        }
    	    }
    	}*/
    	
		
		BoolQueryBuilder should = QueryBuilders.boolQuery()
					.should(QueryBuilders.matchQuery("title", "Brown fox"))
					.should(QueryBuilders.matchQuery("body", "Brown fox"));
		
    	
    	SearchResponse searchResponse = client.prepareSearch("my_index")
                 .setTypes("my_type")
                 .setQuery(should)
                 .setSize(20)
                 .execute()
                 .actionGet();
    	 SearchHits hits = searchResponse.getHits(); 
         System.out.println("查到记录数："+hits.getTotalHits());
         SearchHit[] searchHists = hits.getHits();
         if(searchHists.length>0){
             for(SearchHit hit:searchHists){
                 String name =  (String) hit.getSourceAsMap().get("title");
                 String age = (String)hit.getSourceAsMap().get("body");
                 System.out.format("name:%s ,age :%s \n",name ,age);
             }
         }
    }

    @Test
    public void dis_maxQuery() {
    	/*localhost:9200/my_index/my_type/_search
    	{
		    "query": {
		        "dis_max": {
		            "queries": [
		                { "match": { "title": "Brown fox" }},
		                { "match": { "body":  "Brown fox" }}
		            ]
		        }
		    }
		}*/
    	
    	
    	DisMaxQueryBuilder disMaxQueryBuilder = QueryBuilders.disMaxQuery().add(QueryBuilders.matchQuery("title", "Brown fox"))
    								.add(QueryBuilders.matchQuery("body", "Brown fox"));
    	
    	SearchResponse searchResponse = client.prepareSearch("my_index")
    			.setTypes("my_type")
    			.setQuery(disMaxQueryBuilder)
    			.setSize(20)
    			.execute()
    			.actionGet();
    	SearchHits hits = searchResponse.getHits(); 
    	System.out.println("查到记录数："+hits.getTotalHits());
    	SearchHit[] searchHists = hits.getHits();
    	if(searchHists.length>0){
    		for(SearchHit hit:searchHists){
    			String name =  (String) hit.getSourceAsMap().get("title");
    			String age = (String)hit.getSourceAsMap().get("body");
    			float score = hit.getScore();
    			System.out.format("name:%s ,age :%s , score :%f \n",name ,age, score);
    		}
    	}
    }

    @Test
    public void multi_matchQuery() {
    	/*localhost:9200/my_index/my_type/_search
    	{
		    "multi_match": {
		        "query":                "Quick brown fox",
		        "type":                 "best_fields", 
		        "fields":               [ "title", "body" ],
		        "tie_breaker":          0.3,
		        "minimum_should_match": "30%" 
		    }
		}*/
    	
    	MultiMatchQueryBuilder minimumShouldMatch = QueryBuilders.multiMatchQuery("Quick brown fox", "title", "body").type(Type.BEST_FIELDS).tieBreaker(0.3f).minimumShouldMatch("30%");
    	
    	SearchResponse searchResponse = client.prepareSearch("my_index")
    			.setTypes("my_type")
    			.setQuery(minimumShouldMatch)
    			.setSize(20)
    			.execute()
    			.actionGet();
    	SearchHits hits = searchResponse.getHits(); 
    	System.out.println("查到记录数："+hits.getTotalHits());
    	SearchHit[] searchHists = hits.getHits();
    	if(searchHists.length>0){
    		for(SearchHit hit:searchHists){
    			String name =  (String) hit.getSourceAsMap().get("title");
    			String age = (String)hit.getSourceAsMap().get("body");
    			float score = hit.getScore();
    			System.out.format("name:%s ,age :%s , score :%f \n",name ,age, score);
    		}
    	}
    }
    
    @Test
    public void queryStrignQuery() {
    	/*localhost:9200/my_index/my_type/_search
    	{
		    "multi_match": {
		        "query":                "Quick brown fox",
		        "type":                 "best_fields", 
		        "fields":               [ "title", "body" ],
		        "tie_breaker":          0.3,
		        "minimum_should_match": "30%" 
		    }
		}*/
    	
    	
		QueryStringQueryBuilder queryStringQuery = QueryBuilders.queryStringQuery("Quick brown fox");
		queryStringQuery.field("title");
		queryStringQuery.field("body");
		queryStringQuery.type(Type.BEST_FIELDS);
		queryStringQuery.tieBreaker(0.3f).minimumShouldMatch("30%");
		
    	SearchResponse searchResponse = client.prepareSearch("my_index")
    			.setTypes("my_type")
    			.setQuery(queryStringQuery)
    			.setSize(20)
    			.execute()
    			.actionGet();
    	SearchHits hits = searchResponse.getHits(); 
    	System.out.println("查到记录数："+hits.getTotalHits());
    	SearchHit[] searchHists = hits.getHits();
    	if(searchHists.length>0){
    		for(SearchHit hit:searchHists){
    			String name =  (String) hit.getSourceAsMap().get("title");
    			String age = (String)hit.getSourceAsMap().get("body");
    			float score = hit.getScore();
    			System.out.format("name:%s ,age :%s , score :%f \n",name ,age, score);
    		}
    	}
    }
    
    
}